
using System;
using System.Collections.Generic;
using Xunit;
using Xunit.Extensions;


namespace Boilen.Primitives.Members {

    public class TestInitializationMember {

        [Fact]
        public void constructor_fails_for_null_value( ) {
            string name = "name";
            string type = "type";
            string nullValue = null;

            Assert.Throws<ArgumentNullException>( ( ) => new InitializationMember( name, type, nullValue ) );
        }

        [Fact]
        public void constructor_fails_for_empty_value( ) {
            string name = "name";
            string type = "type";
            string emptyValue = "";

            Assert.Throws<ArgumentException>( ( ) => new InitializationMember( name, type, emptyValue ) );
        }

        [Fact]
        public void constructor_succeeds_typed_value( ) {
            string name = "name";
            string type = "type";
            string value = "value";
            bool expectedIsParameterValue = true;

            var im = new InitializationMember( name, type, value );

            Assert.Equal( im.Name, name );
            Assert.Equal( im.Type, type );
            Assert.Equal( im.Value, value );
            Assert.Equal( im.IsParameterValue, expectedIsParameterValue );
        }

        [Fact]
        public void constructor_succeeds_untyped_value( ) {
            string name = "name";
            string value = "value";
            bool expectedIsParameterValue = false;

            var im = new InitializationMember( name, value );

            Assert.Equal( im.Name, name );
            Assert.Equal( im.Type, "" );
            Assert.Equal( im.Value, value );
            Assert.Equal( im.IsParameterValue, expectedIsParameterValue );
        }


        [Theory]
        [PropertyData( "InitializerValues" )]
        public void IsInstance_returns_expected_value( string name, string type, string scope, string value, bool expectedIsInstance ) {
            var bm = new InitializationMember( name, type, value ) { MemberScope = scope };

            bool isInstance = bm.IsInstance;

            Assert.Equal( isInstance, expectedIsInstance );
        }

        [Theory]
        [PropertyData( "InitializerValues" )]
        public void Write_succeeds_for_valid_arguments( string name, string type, string scope, string value, bool expectedIsInstance ) {
            var expectedLines = new[] { scope + "." + name + " = " + value + ";", "" };
            var writer = new StringBuilderCodeWriter( );
            var bm = new InitializationMember( name, type, value ) { MemberScope = scope };

            bm.Write( writer );

            string[] lines = writer.GetLines( );
            AssertExtensions.EqualCollection( lines, expectedLines );
        }


        #region Utility

        public static IEnumerable<object[]> InitializerValues {
            get {
                yield return new object[] { "fieldName", "fieldType", "fieldScope", "initValue", false };
                yield return new object[] { "fieldName", "fieldType", "fieldScope", "initValue", false };
                yield return new object[] { "count", "int", "this", "0", true };
                yield return new object[] { "staticCount", "int", "StaticCollectionType", "0", false };
            }
        }

        #endregion

    }

}
